package com.tn.rtdata;

import java.io.Serializable;
import java.util.Date;
import java.util.UUID;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

/**
 * A bean that's used to cache information about a fill's heartbeats so that the fill monitor can switch the controlling process if a
 * failure is detected.
 */
public class FillHeartbeat implements Serializable
{
  private UUID controlProcessId;
  private FillIdentity fillIdentity;
  private Date lastHeartbeat;

  /**
   * Creates a new <code>FillHeartbeat</code> with the last heartbeat set to the current date.
   *
   * @param controlProcessId the id of the control process.
   * @param fillIdentity the fill identity.
   */
  public FillHeartbeat(FillIdentity fillIdentity, UUID controlProcessId)
  {
    this.controlProcessId = controlProcessId;
    this.fillIdentity = fillIdentity;
    this.lastHeartbeat = new Date();
  }

  /**
   * Creates a new <code>FillHeartbeat</code> with the last heartbeat set to the current date.
   *
   * @param fillHeartbeat the fill heartbeat to copy.
   */
  public FillHeartbeat(FillHeartbeat fillHeartbeat)
  {
    this(fillHeartbeat.fillIdentity, fillHeartbeat.controlProcessId);
  }

  /**
   * Returns the control process id.
   */
  public UUID getControlProcessId()
  {
    return controlProcessId;
  }

  /**
   * Returns the fill identity.
   */
  public FillIdentity getFillIdentity()
  {
    return fillIdentity;
  }

  /**
   * Returns the last heartbeat timestamp.
   */
  public Date getLastHeartbeat()
  {
    return lastHeartbeat;
  }

  /**
   * Compares this object to another for equality.  For another object to be considered equal to a <code>FillHeartbeat</code> the other
   * object must be a <code>FillHeartbeat</code> and must have been initialized with the same values.
   *
   * @param other the other object.
   *
   * @return <code>true</code> if the objects are considered equal, otherwise <code>false</code>.
   */
  @Override
  public boolean equals(Object other)
  {
    return this == other || other != null && getClass() == other.getClass() &&
      new EqualsBuilder()
        .append(getControlProcessId(), ((FillHeartbeat)other).getControlProcessId())
        .append(getFillIdentity(), ((FillHeartbeat)other).getFillIdentity())
        .append(getLastHeartbeat(), ((FillHeartbeat)other).getLastHeartbeat())
        .isEquals();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public int hashCode()
  {
    return new HashCodeBuilder()
      .append(getControlProcessId())
      .append(getFillIdentity())
      .append(getLastHeartbeat())
      .toHashCode();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
      .append("controlProcessId", getControlProcessId())
      .append("fillIdentity", getFillIdentity())
      .append("lastHeartbeat", getLastHeartbeat())
      .toString();
  }
}
